package com.bluishoul.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;

import my.mvc.Annotation.JSONOutputEnabled;
import my.mvc.Annotation.PostMethod;
import my.mvc.RequestContext;

import com.bluishoul.bean.Dish;
import com.bluishoul.bean.User;
import com.bluishoul.order.Order;
import com.bluishoul.order.OrderDetail;

public class OrderAction {

	public static final String SESSION_ORDER_ID = "_orderid_";

	@PostMethod
	@JSONOutputEnabled
	public void makeOrder(RequestContext ctx) throws IOException {
		User user = (User) ctx.user();

		long[] shops1 = ctx.lparams("shop");
		if (shops1.length == 0)
			throw ctx.error("order_specified_shop_null");

		long[] dishes = ctx.lparams("dish");
		byte type = ctx.param("type", Order.ORDER_TYPE_GROUP);

		Order anOrder = new Order();
		String ident = UUID.randomUUID().toString();
		long uid = 0L;
		if (user != null) {
			uid = user.getId();
			anOrder.setUser(user.getId());
			anOrder.setIdent(ident);
		} else {
			anOrder.setIdent(ident);
		}

		anOrder.setType(type);
		anOrder.setIp(ctx.ip());

		if ((user != null && !user.CanAdmin(user)) && anOrder.tooQuick())
			throw ctx.error("order_too_quick");
		// 单点处理

		Set<Long> ss = new HashSet<Long>();
		List<Dish> ds = new ArrayList<Dish>();
		if (dishes != null && dishes.length > 0) {
			for (long d : dishes) {
				Dish dish = Dish.INSTANCE.Get(d);
				if (dish != null) {
					ds.add(dish);
					ss.add(dish.getShop());
				}
			}
		}
		List<Long> shops = new ArrayList<Long>();
		for (long s : shops1) {
			if (!ss.contains(s))
				shops.add(s);
		}

		if (anOrder.Save() > 0) {
			int sum = shops.size() + ds.size();
			List<OrderDetail> details = new ArrayList<OrderDetail>(sum);
			for (long shop : shops) {
				OrderDetail detail = new OrderDetail();
				detail.setType(OrderDetail.TYPE_CREATE_DATA);
				detail.setIdent(ident);
				detail.setUser(uid);
				detail.setOrder(anOrder.getId());
				detail.setShop(shop);
				details.add(detail);
			}
			// 单点菜处理
			for (Dish d : ds) {
				long shop = d.getShop();
				OrderDetail detail = new OrderDetail();
				detail.setType(OrderDetail.TYPE_CREATE_DATA);
				detail.setIdent(ident);
				detail.setUser(uid);
				detail.setOrder(anOrder.getId());
				detail.setShop(shop);
				detail.setDish(d.getId());
				details.add(detail);
			}
			long[] ids = OrderDetail.Save(details);
			if (ids.length != sum) {
				OrderDetail.Delete(ids);
				throw ctx.error("order_save_error");
			}
			HttpSession session = ctx.session(true);
			session.setAttribute(SESSION_ORDER_ID, ident);
			ctx.cookie(SESSION_ORDER_ID, ident, 3 * 3600, true);
			ctx.output_json("share_link", ident);
		} else {
			throw ctx.error("order_create_error");
		}
	}

	@PostMethod
	@JSONOutputEnabled
	public void orderDish(RequestContext ctx) throws ServletException,
			IOException {
		User user = (User) ctx.user();
		String order = ctx.param("order", "");
		if (StringUtils.isBlank(order))
			throw ctx.error("order_specified_order_null");
		long[] dishes = ctx.lparams("dish");
		if (dishes == null || dishes.length == 0){
			ctx.output_json("id", order);
			return;
		}
		Cookie c = ctx.cookie(SESSION_ORDER_ID);
		String ident = "";
		if (user == null && c == null) {
			ident = UUID.randomUUID().toString();
			ctx.cookie(SESSION_ORDER_ID, ident, 3 * 3600, true);
		} else
			ident = c.getValue();
		Order anOrder = Order.INSTANCE.getOrderByIdent(order, 0);
		List<Dish> ds = new ArrayList<Dish>(dishes.length);
		OrderDetail.INSTANCE.deleteDishesByIdent(anOrder.getId(), ident,
				user == null ? 0 : user.getId(), OrderDetail.TYPE_DETAIL_DATA);
		for (long d : dishes) {
			Dish dish = Dish.INSTANCE.Get(d);
			if (dish != null)
				ds.add(dish);
		}
		if (ds.size() == 0)
			ctx.output_json("id", anOrder.getId());
		List<OrderDetail> details = new ArrayList<OrderDetail>(ds.size());
		for (Dish d : ds) {
			long shop = d.getShop();
			OrderDetail detail = new OrderDetail();
			detail.setType(OrderDetail.TYPE_DETAIL_DATA);
			detail.setIdent(ident);
			if (user != null)
				detail.setUser(user.getId());
			detail.setOrder(anOrder.getId());
			detail.setShop(shop);
			detail.setDish(d.getId());
			details.add(detail);
		}
		long[] ids = OrderDetail.Save(details);
		if (ids.length != ds.size()) {
			OrderDetail.Delete(ids);
			throw ctx.error("order_save_error");
		}
		ctx.output_json("id", order);
	}
}
